Skip to content

27 enum枚举

你定义了一堆状态码:PENDING = 0ACTIVE = 1INACTIVE = 2。问题是,这些魔法数字谁记得住?传个3进去谁知道是什么意思?enum模块就是来解决这个问题的,它让你定义有意义的枚举类型。

一、基本用法

1.1 定义枚举

python
from enum import Enum

class Status(Enum):
    PENDING = 0
    ACTIVE = 1
    INACTIVE = 2

# 使用
print(Status.ACTIVE)        # Status.ACTIVE
print(Status.ACTIVE.name)   # 'ACTIVE'
print(Status.ACTIVE.value)  # 1

1.2 访问枚举成员

python
from enum import Enum

class Color(Enum):
    RED = 1
    GREEN = 2
    BLUE = 3

# 通过名称访问
print(Color.RED)       # Color.RED

# 通过值访问
print(Color(1))        # Color.RED

# 比较
print(Color.RED == Color.RED)   # True
print(Color.RED == Color.GREEN) # False

# 遍历
for color in Color:
    print(f"{color.name}: {color.value}")

1.3 函数式创建

python
from enum import Enum

Color = Enum('Color', ['RED', 'GREEN', 'BLUE'])

print(Color.RED)      # Color.RED
print(Color.RED.value) # 1(自动从1开始)

二、auto():自动递增

python
from enum import Enum, auto

class Direction(Enum):
    NORTH = auto()  # 1
    SOUTH = auto()  # 2
    EAST = auto()   # 3
    WEST = auto()   # 4

print(Direction.NORTH.value)  # 1
print(Direction.SOUTH.value)  # 2

三、IntEnum:整数枚举

可以当作整数使用。

python
from enum import IntEnum

class Priority(IntEnum):
    LOW = 1
    MEDIUM = 2
    HIGH = 3

# 可以比较大小
print(Priority.HIGH > Priority.LOW)  # True

# 可以和整数运算
print(Priority.HIGH + 1)  # 4

# 可以用于需要整数的地方
def process(level: int):
    print(f"处理级别: {level}")

process(Priority.HIGH)  # OK

四、StrEnum:字符串枚举(3.11+)

python
from enum import StrEnum

class Color(StrEnum):
    RED = "red"
    GREEN = "green"
    BLUE = "blue"

# 可以当作字符串使用
print(f"颜色是 {Color.RED}")  # 颜色是 red
print(Color.RED.upper())      # RED

五、Flag:位标志枚举

支持位运算。

python
from enum import Flag, auto

class Permission(Flag):
    READ = auto()     # 1
    WRITE = auto()    # 2
    EXECUTE = auto()  # 4
    ALL = READ | WRITE | EXECUTE  # 7

# 组合权限
perms = Permission.READ | Permission.WRITE
print(perms)  # Permission.READ|WRITE

# 检查权限
print(Permission.READ in perms)    # True
print(Permission.EXECUTE in perms) # False

# 添加权限
perms |= Permission.EXECUTE
print(perms)  # Permission.READ|WRITE|EXECUTE

5.1 IntFlag

整数版本的Flag。

python
from enum import IntFlag

class Color(IntFlag):
    RED = 1
    GREEN = 2
    BLUE = 4

# 可以和整数运算
mixed = Color.RED | Color.GREEN
print(mixed)        # Color.RED|GREEN
print(mixed.value)  # 3

六、@unique:值唯一

python
from enum import Enum, unique

@unique
class Status(Enum):
    PENDING = 0
    ACTIVE = 1
    INACTIVE = 2
    # DUPLICATE = 0  # ValueError: duplicate values found

七、枚举方法

7.1 自定义方法

python
from enum import Enum

class Planet(Enum):
    MERCURY = (3.303e+23, 2.4397e6)
    VENUS = (4.869e+24, 6.0518e6)
    EARTH = (5.976e+24, 6.37814e6)

    def __init__(self, mass, radius):
        self.mass = mass
        self.radius = radius

    def surface_gravity(self):
        G = 6.67300E-11
        return G * self.mass / (self.radius ** 2)

print(Planet.EARTH.surface_gravity())  # 9.8...

7.2 类方法

python
from enum import Enum

class Season(Enum):
    SPRING = 1
    SUMMER = 2
    AUTUMN = 3
    WINTER = 4

    @classmethod
    def from_month(cls, month):
        if month in (3, 4, 5):
            return cls.SPRING
        elif month in (6, 7, 8):
            return cls.SUMMER
        elif month in (9, 10, 11):
            return cls.AUTUMN
        else:
            return cls.WINTER

print(Season.from_month(6))  # Season.SUMMER

八、实战场景

8.1 状态机

python
from enum import Enum

class OrderStatus(Enum):
    CREATED = "created"
    PAID = "paid"
    SHIPPED = "shipped"
    DELIVERED = "delivered"
    CANCELLED = "cancelled"

class Order:
    def __init__(self):
        self.status = OrderStatus.CREATED

    def pay(self):
        if self.status != OrderStatus.CREATED:
            raise ValueError(f"无法从{self.status}转换到已支付")
        self.status = OrderStatus.PAID

    def ship(self):
        if self.status != OrderStatus.PAID:
            raise ValueError(f"无法从{self.status}转换到已发货")
        self.status = OrderStatus.SHIPPED

8.2 配置常量

python
from enum import Enum

class LogLevel(Enum):
    DEBUG = 10
    INFO = 20
    WARNING = 30
    ERROR = 40
    CRITICAL = 50

class Config:
    def __init__(self):
        self.log_level = LogLevel.INFO

    def should_log(self, level: LogLevel):
        return level.value >= self.log_level.value

config = Config()
print(config.should_log(LogLevel.DEBUG))    # False
print(config.should_log(LogLevel.ERROR))    # True

8.3 错误码

python
from enum import IntEnum

class ErrorCode(IntEnum):
    SUCCESS = 0
    INVALID_INPUT = 1001
    NOT_FOUND = 1002
    PERMISSION_DENIED = 1003
    INTERNAL_ERROR = 5000

def process(data):
    if not data:
        return ErrorCode.INVALID_INPUT
    return ErrorCode.SUCCESS

result = process(None)
if result != ErrorCode.SUCCESS:
    print(f"错误: {result.name} ({result.value})")

九、枚举的限制

9.1 不能修改值

python
from enum import Enum

class Color(Enum):
    RED = 1

# Color.RED = 2  # AttributeError: Cannot reassign members

9.2 值可以重复(除非用@unique)

python
from enum import Enum

class Color(Enum):
    RED = 1
    CRIMSON = 1  # OK,和RED是同一个值
    BLUE = 2

print(Color.CRIMSON is Color.RED)  # True

十、总结

enum模块的核心:

用途
Enum基础枚举
IntEnum整数枚举
StrEnum字符串枚举(3.11+)
Flag位标志枚举
IntFlag整数位标志
auto()自动递增值
@unique确保值唯一

使用场景:

  • 状态码、错误码
  • 配置常量
  • 类型标识
  • 权限标志

比直接用数字或字符串好:有类型检查、有自动补全、代码更清晰。